#include "stm32f4xx_hal.h"
#include "iic.h"
#include "tim.h"
#include "usart.h"
#include "delay.h"

#define GPIO_SDA GPIOB
#define GPIO_SCL GPIOB
#define GPIO_SDA_PIN GPIO_PIN_7
#define GPIO_SCL_PIN GPIO_PIN_6

void SDA_IN(void){
        GPIO_InitTypeDef GPIO_InitStruct;
        /*Configure GPIO pins : PB7 */
        GPIO_InitStruct.Pin = GPIO_SDA_PIN;
        GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
        HAL_GPIO_Init(GPIO_SDA, &GPIO_InitStruct);

}
void SDA_OUT(void){
        GPIO_InitTypeDef GPIO_InitStruct;
        /*Configure GPIO pins : PB7 */
        GPIO_InitStruct.Pin = GPIO_SDA_PIN;
        GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
        HAL_GPIO_Init(GPIO_SDA, &GPIO_InitStruct);

}

void SCL_OUT(void){
		GPIO_InitTypeDef GPIO_InitStruct;
        /*Configure GPIO pins : PB6*/
        GPIO_InitStruct.Pin = GPIO_SCL_PIN;
        GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
        HAL_GPIO_Init(GPIO_SCL, &GPIO_InitStruct);

}
void SDA_H(void)
{
  HAL_GPIO_WritePin(GPIO_SDA,GPIO_SDA_PIN, GPIO_PIN_SET);
}
void SDA_L(void)
{
  HAL_GPIO_WritePin(GPIO_SDA,GPIO_SDA_PIN, GPIO_PIN_RESET);
}
void SCL_H(void)
{
  HAL_GPIO_WritePin(GPIO_SCL,GPIO_SCL_PIN, GPIO_PIN_SET);
}
void SCL_L(void)
{
  HAL_GPIO_WritePin(GPIO_SCL,GPIO_SCL_PIN, GPIO_PIN_RESET);
}
GPIO_PinState SDA_READ(void)
{
	GPIO_PinState ret;
	ret = HAL_GPIO_ReadPin(GPIO_SDA,GPIO_SDA_PIN);
	return ret;
}

void iic2_init(void)
{
	__HAL_RCC_GPIOB_CLK_ENABLE();
	SDA_OUT();
	SCL_OUT();
	SDA_H();
	SCL_H();

}

/*the signal of start*/
HAL_StatusTypeDef iic2_start(void)
{
	SDA_OUT();
	SDA_H();
	SCL_H();
	delay_us(5);		/*建立发送起始条件*/
	if(0==SDA_READ())
		return HAL_ERROR;
	SDA_L();			/*发送起始信号，SCL=1，SDA由1变为0*/
	delay_us(5);
	if(1==SDA_READ())
		return HAL_ERROR;
	SCL_L();			/*钳住IIC总线，准备发送或者接收数据*/
	return HAL_OK;
}

/*the signal of stop*/
void iic2_stop(void)
{
	SDA_OUT();
	SDA_L();
	SCL_L();
	delay_us(5);
	SCL_H();
	SDA_H();			/*发送结束信号，SCL=1，SDA由0变为1*/
	delay_us(5);



}

/*send acknowledge signal*/
void iic2_ack(void)
{
	SCL_L();
	delay_us(2);
	SDA_OUT();
	SDA_L();
	delay_us(2);
	SCL_H();
	delay_us(2);
	SCL_L();			/*钳住IIC总线，以便继续接收数据*/
	delay_us(2);

}

/*send no acknowledge signal*/
void iic2_nack(void)
{
	SCL_L();
	SDA_OUT();
	SDA_H();
	delay_us(2);
	SCL_H();
	delay_us(2);
	SCL_L();			/*钳住IIC总线，以便接收停止信号*/
	delay_us(2);

}

/*Receive and check acknowledge signal*/
uint8_t iic2_wait_ack(void)
{
	uint8_t Errtmie = 0;
	SDA_IN();
	SDA_H();
	delay_us(2);
	SCL_H();
	delay_us(2);
	while(SDA_READ())
	{
		Errtmie++;
		if(Errtmie>=0xff)
		{
			SCL_L();
			delay_us(2);
			return 1;
		}
	}
	SCL_L();
	delay_us(2);
	return 0;
}
/*
函数原型：		uint8_t iic2_recv_single_byte(unsigned char ack)
功能：			接收从器件传来的数据并发送应答信号
*/
uint8_t iic2_recv_single_byte(unsigned char ack)
{
	uint8_t i=8;
	uint8_t iic2_buff = 0x00;
	SDA_IN();
	while(i--)
	{

		SCL_L();			/*置时钟线为低，准备接收数据位*/
		delay_us(2);
		SCL_H();			/*置时钟线为高，使数据位有效*/
		iic2_buff <<= 1;
		delay_us(2);
		if(SDA_READ())
			iic2_buff |=0x01;			/*读取数据位*/
		else
			iic2_buff &=0xFE;
	}
	if(!ack)
		iic2_nack();
	else
		iic2_ack();
	return iic2_buff;

}
/*
函数原型：		void iic2_send_single_byte(uint8_t iic2_buff)
功能：			主器件向从器件发送数据
*/
void iic2_send_single_byte(uint8_t iic2_buff)
{

	uint8_t i=8;
	SDA_OUT();
	SCL_L();
	delay_us(2);
	for(i=8;i>0;i--)
	{
		HAL_GPIO_WritePin(GPIO_SDA,GPIO_SDA_PIN, (GPIO_PinState)((iic2_buff & 0x80)>>7));
		iic2_buff <<= 1;
		delay_us(2);
		SCL_H();
		delay_us(2);
		SCL_L();
		delay_us(2);
	}
}
